package com.smart.primary.util;

import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtil {
    private static final int[] DAY_OF_MONTH = new int[] { 31, 28, 31, 30, 31,
	            30, 31, 31, 30, 31, 30, 31 };
    public static final String DAT="yyyy-MM";
    public static final String DATE="yyyy-MM-dd";
    public static final String DATE_TIME="yyyy-MM-dd HH:mm:ss";
    public static final String DATE_TIME_MS="yyyy-MM-dd HH:mm:ss.SSS";
    public static final String TODAY="TODAY";
    public static final String YESTERDAY="YESTERDAY";
    public static final String MONTH="MONTH";
    public static final String PRE_MONTH="PRE_MONTH";

/**
 *
 */

/*
 * long 类型转化
 */
    public static String longToString(long currentTime, String formatType){
        if(StringUtils.isBlank(formatType)){
            return null;
        }
        Date date = longToDate(currentTime); // long类型转成Date类型
        return dateToString(date, formatType); // date类型转成String
    }
    public static String longToString(long currentTime) {
        Date date = longToDate(currentTime); // long类型转成Date类型
        return dateToString(date, DATE_TIME); // date类型转成String
    }
    public static Date longToDate(long currentTime){
        return new Date(currentTime);
    }


/*
 *  date 类型转化
 */
    public static String dateToString(Date data, String formatType) {
        if(StringUtils.isBlank(formatType)){
            return null;
        }
        return data==null?null:new SimpleDateFormat(formatType).format(data);
    }
    public static String dateToString(Date data) {
        return data==null?null:new SimpleDateFormat(DATE_TIME).format(data);
    }
    public static String dateToString(String formatType) {
        return formatType==null?null:new SimpleDateFormat(formatType).format(new Date());
    }

/*
 * string 类型转化
 */
    public static Date stringToDate(String strTime, String formatType){
        if(StringUtils.isBlank(strTime) || StringUtils.isBlank(formatType)){
            return null;
        }
        Date date = null;
        try {
            date = new SimpleDateFormat(formatType).parse(strTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }


    public static Date stringToDate(String strTime){
        if(StringUtils.isBlank(strTime)){
            return null;
        }
        SimpleDateFormat sf=null;
        try {
            if(checkDate(strTime,DATE_TIME_MS)){
                sf= new SimpleDateFormat(DATE_TIME_MS);
            }else if(checkDate(strTime,DATE_TIME)){
                sf = new SimpleDateFormat(DATE_TIME);
            }else if(checkDate(strTime,DATE)){
                sf = new SimpleDateFormat(DATE);
            }else {
                return null;
            }
            return sf.parse(strTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static long stringToLong(String strTime, String formatType){
        if(StringUtils.isBlank(strTime) || StringUtils.isBlank(formatType)){
            return 0;
        }
        Date date = stringToDate(strTime, formatType); // String类型转成date类型
        return date == null?0:date.getTime();
    }

    public static long stringToLong(String strTime){
        if(StringUtils.isBlank(strTime)){
            return 0;
        }
        Date date = stringToDate(strTime);
        return date == null?0:date.getTime();
    }
    /**
     * 把日期字符串转换为util.date类型
     * @param strDate
     *            日期字符串(yyyy-MM-dd)
     * @return java.sql.date 类型
     */
    public static Date getDate(String strDate) {
        return java.sql.Date.valueOf(strDate);
    }

/*
 * 日期累加
 */
    public static String addStrDay(String strDate, int dayNum) {
        if(StringUtils.isBlank(strDate)){
            return null;
        }
        SimpleDateFormat sf=null;
        if(checkDate(strDate,DATE_TIME_MS)){
            sf= new SimpleDateFormat(DATE_TIME_MS);
        }else if(checkDate(strDate,DATE_TIME)){
            sf = new SimpleDateFormat(DATE_TIME);
        }else if(checkDate(strDate,DATE)){
            sf = new SimpleDateFormat(DATE);
        }else {
            return null;
        }
        Date date = null;
        try {
            date = sf.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, dayNum);
        String sqldate = sf.format(c.getTime());
        return sqldate;
    }
    public static String addStrDay(int dayNum) {
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, dayNum);
        return dateToString(c.getTime());
    }

    /**
     * 取得指定天数后的时间
     *
     */
    public static Date addDay(Date date, int dayAmount) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, dayAmount);
        return calendar.getTime();
    }
    public static Date addDay(int dayAmount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, dayAmount);
        return calendar.getTime();
    }

    /**
     * 取得指定小时数后的时间
     */
    public static Date addHour(Date date, int hourAmount) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, hourAmount);
        return calendar.getTime();
    }
    public static Date addHour(int hourAmount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.HOUR, hourAmount);
        return calendar.getTime();
    }
    /**
     * 取得指定分钟数后的时间
     */
    public static Date addMinute(Date date, int minuteAmount) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minuteAmount);
        return calendar.getTime();
    }

    public static Date addMinute(int minuteAmount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, minuteAmount);
        return calendar.getTime();
    }
    public static String addStrMinute(String strDate, int minuteAmount) {
        if(StringUtils.isBlank(strDate)){
            return null;
        }
        SimpleDateFormat sf=null;
        if(checkDate(strDate,DATE_TIME_MS)){
            sf= new SimpleDateFormat(DATE_TIME_MS);
        }else if(checkDate(strDate,DATE_TIME)){
            sf = new SimpleDateFormat(DATE_TIME);
        }else if(checkDate(strDate,DATE)){
            sf = new SimpleDateFormat(DATE);
        }else {
            return null;
        }
        Date date = null;
        try {
            date = sf.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, minuteAmount);
        String sqldate = sf.format(c.getTime());
        return sqldate;
    }
    public static String addStrMinute(int minuteAmount) {
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.MINUTE, minuteAmount);
        return dateToString(c.getTime());
    }

/**
 * 校验日期格式是否正确
 */
    public static boolean checkDate(String strTime,String formatType) {
        if(StringUtils.isBlank(strTime) || StringUtils.isBlank(formatType)){
            return false;
        }
        boolean bool=true;
        try {
            new SimpleDateFormat(formatType).parse(strTime);
        } catch (ParseException e) {
            bool=false;
        }
        return bool;
    }

    /**
     * 根据某星期几的英文名称来获取该星期几的中文数. <br>
     * e.g. <li>monday -> 一</li> <li>sunday -> 日</li>
     * 
     * @param englishWeekName
     *            星期的英文名称
     * @return 星期的中文数
     */
    public static String getChineseWeekNumber(String englishWeekName) {
        if ("monday".equalsIgnoreCase(englishWeekName)) {
            return "一";
        }

        if ("tuesday".equalsIgnoreCase(englishWeekName)) {
            return "二";
        }

        if ("wednesday".equalsIgnoreCase(englishWeekName)) {
            return "三";
        }

        if ("thursday".equalsIgnoreCase(englishWeekName)) {
            return "四";
        }

        if ("friday".equalsIgnoreCase(englishWeekName)) {
            return "五";
        }

        if ("saturday".equalsIgnoreCase(englishWeekName)) {
            return "六";
        }

        if ("sunday".equalsIgnoreCase(englishWeekName)) {
            return "日";
        }
        return null;
    }


    public static Date getDate(int year, int month, int date) {
        return getDate(year, month, date, 0, 0);
    }
    public static Date getDate(int year, int month, int date, int hourOfDay,int minute) {
        return getDate(year, month, date, hourOfDay, minute, 0);
    }
    public static Date getDate(int year, int month, int date, int hourOfDay,
            int minute, int second) {
        Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, date, hourOfDay, minute, second);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 取得某个日期是星期几，星期日是1，依此类推
     * 
     * @param date
     *            日期
     * @return 星期几
     */
    public static int getDayOfWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_WEEK);
    }



    /**
     * 取得一个月最多的天数
     * 
     * @param year
     *            年份
     * @param month
     *            月份，0表示1月，依此类推
     * @return 最多的天数
     */
    public static int getMaxDayOfMonth(int year, int month) {
        if (month == 1 && isLeapYear(year)) {
            return 29;
        }
        return DAY_OF_MONTH[month];
    }

    public static Date getStartHour(int hour){
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.set(Calendar.HOUR_OF_DAY, hour);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
    public static Date getEndHour(int hour){
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.set(Calendar.HOUR_OF_DAY, hour);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return cal.getTime();
    }
    /**
     * 获取某天的起始时间, e.g. 2005-10-01 00:00:00.000
     * 
     * @param date
     *            日期对象
     * @return 该天的起始时间
     */
    public static Date getStartDate(Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }


    /**
     * 获取某天的结束时间, e.g. 2005-10-01 23:59:59.999
     *
     * @param date
     *            日期对象
     * @return 该天的结束时间
     */
    public static Date getEndDate(Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return cal.getTime();
    }
    public static Date getStartMonth(Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
    public static Date getEndMonth(Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return cal.getTime();
    }
    public static Date getStartMonth(Date date,Integer in) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, in);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static Date getEndMonth(Date date,Integer in) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, in);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return cal.getTime();
    }


    /**
     * 判断是否是闰年
     * 
     * @param year
     *            年份
     * @return 是true，否则false
     */
    public static boolean isLeapYear(int year) {
        Calendar calendar = Calendar.getInstance();
        return ((GregorianCalendar) calendar).isLeapYear(year);
    }

    /**
     * 取得一年中的第几周。
     * 
     * @param date
     * @return
     */
    public static int getWeekOfYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 获取上周的指定星期的日期。
     * 
     * @param dayOfWeek
     *            星期几，取值范围是 {@link Calendar#MONDAY} - {@link Calendar#SUNDAY}
     */
    public static Date getDateOfPreviousWeek(int dayOfWeek) {
        if (dayOfWeek > 7 || dayOfWeek < 1) {
            throw new IllegalArgumentException("参数必须是1-7之间的数字");
        }

        return getDateOfRange(dayOfWeek, -7);
    }

    /**
     * 获取本周的指定星期的日期。
     * 
     * @param dayOfWeek
     *            星期几，取值范围是 {@link Calendar#MONDAY} - {@link Calendar#SUNDAY}
     */
    public static Date getDateOfCurrentWeek(int dayOfWeek) {
        if (dayOfWeek > 7 || dayOfWeek < 1) {
            throw new IllegalArgumentException("参数必须是1-7之间的数字");
        }
        return getDateOfRange(dayOfWeek, 0);
    }

    /**
     * 获取下周的指定星期的日期。
     * 
     * @param dayOfWeek
     *            星期几，取值范围是 {@link Calendar#MONDAY} - {@link Calendar#SUNDAY}
     */
    public static Date getDateOfNextWeek(int dayOfWeek) {
        if (dayOfWeek > 7 || dayOfWeek < 1) {
            throw new IllegalArgumentException("参数必须是1-7之间的数字");
        }
        return getDateOfRange(dayOfWeek, 7);
    }

    private static Date getDateOfRange(int dayOfWeek, int dayOfRange) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, dayOfWeek);
        cal.set(Calendar.DATE, cal.get(Calendar.DATE) + dayOfRange);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

//    public static Date getStartDate(String keyword) {
//        if(StringUtils.isBlank(keyword)){
//            return null;
//        }
//        switch (keyword.toUpperCase()){
//            case TODAY:
//                return DateUtil.getStartDate(new Date());
//            case YESTERDAY:
//                return DateUtil.getStartDate(DateUtil.addDay(-1));
//            case MONTH:
//                return DateUtil.getStartMonth(new Date());
//            case PRE_MONTH:
//                return DateUtil.getStartMonth(new Date(),-1);
//             default:
//                 return null;
//        }
//    }
//
//    public static Date getEndDate(String keyword) {
//        if(StringUtils.isBlank(keyword)){
//            return null;
//        }
//        switch (keyword.toUpperCase()){
//            case TODAY:
//                return DateUtil.getEndDate(new Date());
//            case YESTERDAY:
//                return DateUtil.getEndDate(DateUtil.addDay(-1));
//            case MONTH:
//                return DateUtil.getEndMonth(new Date());
//            case PRE_MONTH:
//                return DateUtil.getEndMonth(new Date(),-1);
//            default:
//                return null;
//        }
//    }
    /**
     * date2比date1多的天数
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1,Date date2)
    {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1= cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if(year1 != year2)   //同一年
        {
            int timeDistance = 0 ;
            for(int i = year1 ; i < year2 ; i ++)
            {
                if(i%4==0 && i%100!=0 || i%400==0)    //闰年
                {
                    timeDistance += 366;
                }
                else    //不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2-day1) ;
        }
        else    //不同年
        {
            System.out.println("判断day2 - day1 : " + (day2-day1));
            return day2-day1;
        }
    }

    // 时间段
    //0,8
    public static Date getStartQuantum(String keyword){
        Integer in=null;
        try {
            if(keyword.contains(",")){
                in=Integer.parseInt(keyword.substring(0,keyword.indexOf(",")));
            }else{
                in=Integer.parseInt(keyword);
            }
        }catch (Exception e){
            return  null;
        }
        return getStartHour(in);
    }
    // 时间段
    //0,8
    public static Date getEndQuantum(String keyword){
        Integer in=null;
        if(keyword.contains(",")){
            in=Integer.parseInt(keyword.substring(0,keyword.indexOf(",")));
        }else{
            in=Integer.parseInt(keyword);
        }
        return getStartHour(in);
    }
    //获取本周的开始时间
    public static Date getBeginDayOfWeek() {
        Date date = new Date();
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return getStartDate(cal.getTime());
    }
    //获取本周的结束时间
    public static Date getEndDayOfWeek(){
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfWeek());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        return getEndDate(weekEndSta);
    }
    public static void main(String[] args) {
        System.out.println(dateToString(getStartDate(new Date())));
        System.out.println(dateToString(getEndDate(new Date())));
        System.out.println(dateToString(getBeginDayOfWeek()));
        System.out.println(dateToString(getEndDayOfWeek()));
        System.out.println(dateToString(DateUtil.getStartDate(DateUtil.addDay(-7))));
    }

}
